package Visitor;

import Entities.*;
import Entities.Advantages.*;

public class BallCollisionVisitor implements Visitor.IVisitor {

    private Ball ball;

    public BallCollisionVisitor(Ball ball) {
        this.ball = ball;
    }

    @Override
    public Drawable visit(Bar bar) {
        if (bar.getY() - 1 <= ball.getY() + ball.getRadio() * 2 && ball.getY() + ball.getRadio() * 2 <= bar.getY() + 1) {
            if (bar.getX() - ball.getRadio() <= ball.getX() + ball.getRadio() && ball.getX() + ball.getRadio() < bar.getX() + (bar.getWidth() / 2)) {
                double distance = bar.getWidth() / 2;
                double newDx = ball.getMaxDx() * ((ball.getX() % distance) + (ball.getRadio() / 2)) / distance;
                ball.setDy(ball.getDy() * -1);
                ball.setDx(newDx);
                if (ball.getDx() > 0) {
                    ball.setDx(ball.getDx() * -1);
                }
                return bar;
            } else {
                if (bar.getX() + (bar.getWidth() / 2) <= ball.getX() + ball.getRadio() && ball.getX() + ball.getRadio() <= bar.getX() + bar.getWidth() + ball.getRadio()) {
                    double distance = bar.getWidth() / 2;
                    double newDx = ball.getMaxDx() * ((ball.getX() % distance) + (ball.getRadio() / 2)) / distance;
                    ball.setDy(ball.getDy() * -1);
                    ball.setDx(newDx);
                    if (ball.getDx() < 0) {
                        ball.setDx(ball.getDx() * -1);
                    }
                    return bar;
                }
            }
        }
        return null;
    }

    @Override
    public Drawable visit(Ball ball) {
        return null;
    }

    @Override
    public Drawable visit(Boundary boundary) {
        if (ball.getX() <= boundary.getX() || ball.getX() + ball.getRadio() * 2 >= boundary.getWidth()) {
            ball.setDx(ball.getDx() * -1);
            return boundary;
        }

        if (ball.getY() <= boundary.getY() || ball.getY() + ball.getRadio() * 2 >= boundary.getHeight()) {
            ball.setDy(ball.getDy() * -1);
            return boundary;
        }
        return null;
    }

    @Override
    public Drawable visit(IAdvantage advantage) {
        return null;
    }

    @Override
    public Drawable visit(Brick brick) {
        if (brick.getX() - ball.getRadio() <= ball.getX() + ball.getRadio() && ball.getX() + ball.getRadio() <= brick.getX() + brick.getWidth() + ball.getRadio()) {
            if (brick.getY() + brick.getHeight() <= ball.getY() && ball.getY() <= brick.getY() + brick.getHeight() + 2) {
                ball.setDy(ball.getDy() * - 1);
                return brick;
            }
            if (brick.getY() - 2 <= ball.getY() + ball.getRadio() * 2 && ball.getY() + ball.getRadio() * 2 <= brick.getY()) {
                ball.setDy(ball.getDy() * - 1);
                return brick;
            }
        }
        if (brick.getY() <= ball.getY() + ball.getRadio() && ball.getY() <= brick.getY() + brick.getHeight()) {
            if (brick.getX() - 2 <= ball.getX() + ball.getRadio() * 2 && ball.getX() + ball.getRadio() * 2 <= brick.getX()) {
                ball.setDx(ball.getDx() * - 1);
                return brick;
            }
            if (brick.getX() + brick.getWidth() <= ball.getX() && ball.getX() <= brick.getX() + brick.getWidth() + 2) {
                ball.setDx(ball.getDx() * - 1);
                return brick;
            }
        }
        return null;
    }

    @Override
    public Drawable visit(Drawable drawable) {
        return null;
    }

    @Override
    public Drawable visit(Hinder hinder) {
        return null;
    }

    @Override
    public Drawable visit(DecreaseBarSize dicreaseBarSize) {
        return null;
    }

    @Override
    public Drawable visit(IncreaseBarSize increaseBarSize) {
        return null;
    }

    @Override
    public Drawable visit(DecreaseBallSpeed drecreaseBallSpeed) {
        return null;
    }

    @Override
    public Drawable visit(IncreaseBallSpeed increaseBallSpeed) {
        return null;
    }

    @Override
    public Drawable visit(MissileAdvantage missileAdvantage) {
        return null;
    }

    @Override
    public Drawable visit(ThreeBallsAdvantage threeBallsAdvantage) {
        return null;
    }
}
